package com.mobile.common.base.hibernate;

import java.io.Serializable;
import java.util.Map;

import org.apache.commons.lang.ArrayUtils;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.impl.CriteriaImpl;
import org.hibernate.transform.ResultTransformer;
import org.springframework.util.Assert;

import com.mobile.common.base.support.Page;

@SuppressWarnings("unchecked")
public abstract class SimpleDao<T,PK extends Serializable> extends HibernateDao<T,PK> {

	public SimpleDao() {}
	public SimpleDao(Class<T> entityClass) {
		super(entityClass);
	}

	/**
	 * Criteria分页
	 * @param criteria
	 * @param pageNo	当前页号
	 * @param pageSize	每页数据量
	 * @return
	 */
	public Page<T> findPageByCriteria(Criteria criteria, int pageNo, int pageSize){
		Page<T> page = new Page<T>();
		page.setTotalSize(resultCounts(criteria));
		page.setPageNo(pageNo);
		page.setPageSize(pageSize);
		setPageParams(criteria, page);
		page.setResult(criteria.list());
		return page;
	}
	/**
	 * hql查询
	 * @param queryString	hql查询语句
	 * @param params		hql中的参数
	 * @return
	 */
	public Query createQuery(String queryString, Map<String, Object> params) {
		Assert.hasText(queryString, "queryString不能为空");
		Query query = getSession().createQuery(queryString);
		if (params != null)
			query.setProperties(params);
		return query;
	}
	public Query createQuery(String queryString, Object ... values) {
		Assert.hasText(queryString, "queryString不能为空");
		Query query = getSession().createQuery(queryString);
		if (ArrayUtils.isNotEmpty(values)) {
			for (int i = 0; i < values.length; i++)
				query.setParameter(i, values[i]);
		}
		return query;
	}
	/**
	 * 返回记录总数
	 */
	protected Long resultCounts(Criteria criteria){
		Long total = 0L;
		CriteriaImpl impl = (CriteriaImpl) criteria;
		Projection projection = impl.getProjection();
		ResultTransformer transformer = impl.getResultTransformer();
		total = ((Number) criteria.setProjection(Projections.rowCount()).uniqueResult())
						.longValue();
		criteria.setProjection(projection);
		if (projection == null)
			criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
		if (transformer != null)
			criteria.setResultTransformer(transformer);
		return total;
	}
	/**
	 * 设置Page的参数
	 */
	private Criteria setPageParams(Criteria criteria, Page<T> page){
		criteria.setFirstResult(page.getBeginIndex());
		criteria.setMaxResults(page.getPageSize());
		return criteria;
	}
}
